<template>
  <div class="room-wait">
    <div class="room-wait__wrapper" v-if="room">
      <div class="main-wrapper">
        <Card :style="{ width: '100%' }">
          <TransitionListFade class="player-grid">
            <Card
              class="transition-list-fade-item"
              v-for="(player, idx) in room.players"
              :key="player.id"
            >
              <article class="player-card">
                <div class="player-card__info">
                  <dl class="info-list-dl">
                    <dt>玩家{{ idx + 1 }}</dt>
                    <dd>
                      {{ player.name }}
                      <span
                        v-if="me.id == player.id"
                        class="player-card__info__you"
                        >(你)</span
                      >
                    </dd>
                    <dt>状态</dt>
                    <dd>
                      <TransitionFade>
                        <span
                          :style="stylePlayerState(player.state.status)"
                          :key="player.state.status"
                          >{{ player.state.status | playerStatusToStr }}</span
                        >
                      </TransitionFade>
                    </dd>
                  </dl>
                </div>
                <div class="player-card__avatar">
                  <Avatar
                    style="background-color: #87d068"
                    :src="me.character.imgUrl"
                    >{{ player.name[0] }}</Avatar
                  >
                </div>
              </article>
            </Card>
          </TransitionListFade>
        </Card>
        <div class="status-bar">
          <div class="room-info">
            <Alert show-icon>
              房间: {{ room.id }}
              <Icon type="ios-game-controller-b-outline" slot="icon"></Icon>
              <template slot="desc">
                <dl class="info-list-dl">
                  <dt>房间状态</dt>
                  <dd>{{ room.status | roomStatusToStr }}</dd>
                  <dt>房间人数</dt>
                  <dd>{{ room.players.length }}</dd>
                  <dt>房间难度</dt>
                  <dd>{{ room.setting.difficulty | difficultyToStr }}</dd>
                  <dt>迷题编号</dt>
                  <dd>{{ room.puzzle.id }}</dd>
                  <dd />
                </dl>
                <Button v-if="isHost" @click="handleChangeSetting"
                  >编辑房间设置</Button
                >
              </template>
            </Alert>
          </div>
          <Card :style="{ width: '100%', height: '100%' }">
            <div class="room-setting-control">
              <Button
                :style="{ minWidth: '6rem' }"
                :disabled="isGaming"
                @click="handleChangePlayerStatus"
                >{{ statusValue }}</Button
              >
              <Button
                icon="ios-arrow-dropleft"
                type="primary"
                @click="roomLeaveClicked"
                >离开房间</Button
              >
            </div>
          </Card>
        </div>
      </div>
      <section v-if="isHost" class="host-control">
        <h3>你是房主，<br />当你选择"开始游戏"，玩家才能进入游戏界面。</h3>
        <Button v-if="isHost" @click="gameStartClicked" :disabled="!isAllReady"
          >开始游戏</Button
        >
      </section>
    </div>
    <div class="roomsetting__dialog">
      <Modal
        v-model="roomSettingModelShow"
        @on-ok="handleChangeSettingOK"
        @on-cancel="handleChangeSettingCancel"
      >
        <RoomSettingForm
          :curPlayer="curPlayerSize"
          :formRoomSetting="formRoomSetting"
        />
      </Modal>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from '@/plugins/class-component-hooks'
import {
  Room,
  Player,
  RoomSetting,
  RoomStateChangedSubscription,
  RoomQuery,
  Status,
  GameMode,
  Difficulty,
  RoomSettingInput,
  PlayerStateUpdatedSubscription,
  RoomStatus
} from '../types'
import { ApolloClientOptions } from 'apollo-client'

import RoomSettingForm, {
  FormRoomSetting
} from '@/components/RoomSettingForm.vue'

import { playerModule } from '@/store'
import { Watch, Emit } from 'vue-property-decorator'
import { RoomData } from '../types/room'
import { gqlErrorHandler } from '../util/errorHandler'

@Component({
  components: {
    RoomSettingForm
  }
})
export default class RoomWait extends Vue {
  @Prop() readonly room!: RoomData

  private roomSettingModelShow: boolean = false
  private formRoomSetting: FormRoomSetting = {
    mode: GameMode.Coor,
    difficulty: Difficulty.Easy,
    maxPlayer: 99
  }

  constructor() {
    super()
  }

  @Watch('room.setting', { immediate: true })
  resetFormRoomSetting() {
    this.formRoomSetting = {
      mode: this.room.setting.mode,
      difficulty: this.room.setting.difficulty,
      maxPlayer: this.room.setting.maxPlayer
    }
  }

  @Watch('room')
  onRoomUpdated() {}

  @Emit('roomLeaveClicked')
  roomLeaveClicked() {}

  @Emit('gameStartClicked')
  gameStartClicked() {}

  handleChangeSetting() {
    this.roomSettingModelShow = true
  }

  handleChangeSettingOK() {
    // ignore out
    this.$apollo
      .mutate({
        mutation: require('@/graphql/changeRoomSetting.gql'),
        variables: {
          id: this.room.id,
          input: {
            ...this.formRoomSetting,
            duration: 100
          } as RoomSettingInput
        }
      })
      .catch((err: any) => {
        gqlErrorHandler(this, err)
      })
  }

  handleChangeSettingCancel() {
    this.resetFormRoomSetting()
  }

  handleChangePlayerStatus() {
    let ready: boolean = this.meStatus != Status.Ready
    this.$apollo
      .mutate({
        mutation: require('@/graphql/toggleReady.gql'),
        variables: {
          ready
        }
      })
      .catch((err: Error) => {
        this.$Message.error(err.message)
      })
  }

  get me() {
    return this.room.me
  }

  get isHost() {
    return this.room.me.id === this.room.host.id
  }

  get curPlayerSize() {
    return this.room.playersMap.size
  }

  get meStatus() {
    return this.room.me.state.status
  }

  get statusValue() {
    return this.meStatus == Status.Ready ? '取消准备' : '准备'
  }

  get isGaming() {
    return this.room.status == RoomStatus.Gaming
  }

  get isAllReady() {
    let allReady = true
    this.room.players.every(player => {
      if (player.state.status != Status.Ready) {
        allReady = false
      }
      return allReady
    })

    return allReady
  }

  stylePlayerState(status: Status) {
    let color: string = 'black'
    if (status == Status.Ready) {
      color = '#ff362f'
    } else if (status == Status.Waiting) {
      color = '#2dc515'
    }
    return {
      color: color
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
@import '@/styles/general.scss';

.main-wrapper {
  display: flex;
  justify-content: space-around;
  margin-bottom: 2rem;

  > :first-child {
    margin-right: 1rem;
  }

  @media screen and (max-width: $size-xssm) {
    flex-direction: column-reverse;

    > :first-child {
      margin-top: 1rem;
    }
  }
}

.player-grid {
  display: grid;
  width: 100%;

  grid-auto-rows: 1fr;
  grid-column-gap: 2rem;
  grid-row-gap: 2rem;

  @media screen and (min-width: $size-sm) {
    grid-template-columns: 1fr 1fr;
  }

  @media screen and (min-width: $size-lg) {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

.player-card {
  display: flex;
  // justify-content: space-betw
  > :last-child {
    margin-left: auto;
  }
}

.room-setting-control {
  display: flex;
  justify-content: space-around;

  > :first-child {
    margin-right: 0.5rem;
  }
}

.room-info {
  .info-list-dl {
    margin-bottom: 1rem;
  }
}

.status-bar {
  height: 100%;

  display: flex;
  flex-direction: column;
}

.host-control {
  > :first-child {
    margin-bottom: 0.8rem;
  }
}
</style>
